package com.example.musicaiap.service

import android.content.ComponentName
import android.content.Context
import android.net.Uri
import androidx.media3.common.MediaItem
import androidx.media3.common.MediaMetadata
import androidx.media3.common.Player
import androidx.media3.session.MediaController
import androidx.media3.session.SessionToken
import com.example.musicaiap.data.database.CurrentPlaylistEntity
import com.example.musicaiap.data.repository.MusicRepository
import com.example.musicaiap.data.repository.RoomMusicRepository
import com.example.musicaiap.domain.model.Song
import com.google.common.util.concurrent.ListenableFuture
import com.google.common.util.concurrent.MoreExecutors
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import javax.inject.Inject
import javax.inject.Singleton
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import androidx.media3.common.util.UnstableApi
import android.os.Bundle

/**
 * 辅助类，简化媒体控制
 */
@Singleton
@UnstableApi
class MediaBrowserHelper @Inject constructor(
    @ApplicationContext private val context: Context,
    private val musicRepository: MusicRepository
) {
    private val coroutineScope = CoroutineScope(Dispatchers.Main + Job())
    private var mediaController: MediaController? = null
    private var controllerFuture: ListenableFuture<MediaController>? = null
    
    private val _isConnected = MutableStateFlow(false)
    val isConnected: StateFlow<Boolean> = _isConnected.asStateFlow()
    
    private val _playbackState = MutableStateFlow<PlaybackState>(PlaybackState.Initial)
    val playbackState: StateFlow<PlaybackState> = _playbackState.asStateFlow()
    
    // 进度更新计时器Job
    private var progressUpdateJob: Job? = null
    
    /**
     * 连接到媒体服务
     */
    fun connect() {
        android.util.Log.d("MediaBrowserHelper", "尝试连接到媒体服务")
        
        if (controllerFuture != null && !controllerFuture!!.isDone) {
            android.util.Log.d("MediaBrowserHelper", "连接已在进行中")
            return
        }
        
        val sessionToken = SessionToken(context, ComponentName(context, MusicService::class.java))
        controllerFuture = MediaController.Builder(context, sessionToken).buildAsync()
        
        controllerFuture!!.addListener({
            try {
                mediaController = controllerFuture!!.get()
                mediaController?.addListener(playerListener)
                _isConnected.value = true
                android.util.Log.d("MediaBrowserHelper", "连接成功")
                
                // 启动进度更新任务
                startProgressUpdateJob()
                
                // 连接成功后尝试恢复上次播放
                restorePlaybackState()
            } catch (e: Exception) {
                android.util.Log.e("MediaBrowserHelper", "连接失败: ${e.message}")
                _isConnected.value = false
            }
        }, MoreExecutors.directExecutor())
    }
    
    /**
     * 恢复上次播放状态
     */
    private fun restorePlaybackState() {
        if (mediaController == null) return
        
        coroutineScope.launch {
            try {
                // 如果是RoomMusicRepository，尝试从数据库中恢复播放状态
                if (musicRepository is RoomMusicRepository) {
                    val currentPlaylist = (musicRepository as RoomMusicRepository).getCurrentPlaylist()
                    
                    if (currentPlaylist != null && currentPlaylist.currentSongId != null) {
                        android.util.Log.d("MediaBrowserHelper", "尝试恢复播放状态: ${currentPlaylist.sourceType}")
                        
                        when (currentPlaylist.sourceType) {
                            "LOCAL" -> {
                                // 恢复本地播放列表
                                val localSongs = (musicRepository as RoomMusicRepository).getLocalSongs()
                                if (localSongs.isNotEmpty()) {
                                    val songIndex = localSongs.indexOfFirst { it.id == currentPlaylist.currentSongId }
                                    if (songIndex != -1) {
                                        android.util.Log.d("MediaBrowserHelper", "恢复本地播放列表，歌曲索引: $songIndex")
                                        // 不要自动开始播放，只准备好播放列表
                                        preparePlaylist(localSongs, songIndex, false)
                                    }
                                }
                            }
                            "PLAYLIST" -> {
                                // 恢复普通播放列表
                                val playlistSongs = musicRepository.getPlaylistSongs(currentPlaylist.sourceId)
                                if (playlistSongs.isNotEmpty()) {
                                    val songIndex = playlistSongs.indexOfFirst { it.id == currentPlaylist.currentSongId }
                                    if (songIndex != -1) {
                                        android.util.Log.d("MediaBrowserHelper", "恢复播放列表: ${currentPlaylist.sourceId}，歌曲索引: $songIndex")
                                        preparePlaylist(playlistSongs, songIndex, false)
                                    }
                                }
                            }
                            "SINGLE" -> {
                                // 恢复单曲播放
                                val song = musicRepository.getSongById(currentPlaylist.currentSongId!!)
                                if (song != null) {
                                    android.util.Log.d("MediaBrowserHelper", "恢复单曲播放: ${song.title}")
                                    prepareSong(song, false)
                                }
                            }
                        }
                        
                        // 恢复播放位置
                        if (currentPlaylist.currentPosition > 0) {
                            mediaController?.seekTo(currentPlaylist.currentPosition)
                        }
                    }
                }
            } catch (e: Exception) {
                android.util.Log.e("MediaBrowserHelper", "恢复播放状态失败: ${e.message}")
            }
        }
    }
    
    /**
     * 断开连接
     */
    fun disconnect() {
        android.util.Log.d("MediaBrowserHelper", "断开连接")
        
        try {
            // 保存当前播放位置
            saveCurrentPosition()
            
            // 停止进度更新
            stopProgressUpdateJob()
            
            if (mediaController != null) {
                mediaController?.release()
                mediaController = null
            }
            controllerFuture?.let {
                MediaController.releaseFuture(it)
                controllerFuture = null
            }
            _isConnected.value = false
        } catch (e: Exception) {
            android.util.Log.e("MediaBrowserHelper", "断开连接时出错: ${e.message}")
        }
    }
    
    /**
     * 保存当前播放位置
     */
    private fun saveCurrentPosition() {
        if (mediaController == null) return
        
        val position = mediaController?.currentPosition ?: 0
        val currentMediaItem = mediaController?.currentMediaItem
        
        if (currentMediaItem != null && position > 0 && musicRepository is RoomMusicRepository) {
            coroutineScope.launch {
                try {
                    // 获取当前播放列表信息
                    val currentPlaylist = (musicRepository as RoomMusicRepository).getCurrentPlaylist()
                    
                    if (currentPlaylist != null) {
                        // 更新播放位置
                        val updatedPlaylist = currentPlaylist.copy(
                            currentPosition = position,
                            lastPlayedAt = System.currentTimeMillis()
                        )
                        
                        // 保存回数据库
                        (musicRepository as RoomMusicRepository).currentPlaylistDao.updateCurrentPlaylist(updatedPlaylist)
                        android.util.Log.d("MediaBrowserHelper", "已保存播放位置: $position ms")
                    }
                } catch (e: Exception) {
                    android.util.Log.e("MediaBrowserHelper", "保存播放位置失败: ${e.message}")
                }
            }
        }
    }
    
    /**
     * 启动进度更新任务
     */
    private fun startProgressUpdateJob() {
        // 取消旧的更新任务
        progressUpdateJob?.cancel()
        
        // 创建新的更新任务
        progressUpdateJob = coroutineScope.launch {
            while (isActive) {
                updatePlaybackState()
                
                // 每秒更新一次进度
                delay(1000)
            }
        }
    }
    
    /**
     * 停止进度更新任务
     */
    private fun stopProgressUpdateJob() {
        progressUpdateJob?.cancel()
        progressUpdateJob = null
    }
    
    /**
     * 更新播放状态
     */
    private fun updatePlaybackState() {
        val controller = mediaController ?: return
        
        val currentState = when {
            controller.playbackState == Player.STATE_IDLE -> {
                PlaybackState.Initial
            }
            controller.playbackState == Player.STATE_ENDED -> {
                PlaybackState.Ended(controller.currentMediaItem)
            }
            controller.playbackState == Player.STATE_BUFFERING -> {
                PlaybackState.Buffering(
                    currentMediaItem = controller.currentMediaItem,
                    mediaItemIndex = controller.currentMediaItemIndex,
                    mediaItemCount = controller.mediaItemCount,
                    isPlaying = controller.isPlaying,
                    repeatMode = controller.repeatMode
                )
            }
            controller.playbackState == Player.STATE_READY -> {
                PlaybackState.Ready(
                    currentMediaItem = controller.currentMediaItem,
                    mediaItemIndex = controller.currentMediaItemIndex,
                    mediaItemCount = controller.mediaItemCount,
                    isPlaying = controller.isPlaying,
                    currentPosition = controller.currentPosition,
                    duration = controller.duration,
                    repeatMode = controller.repeatMode
                )
            }
            else -> {
                PlaybackState.Initial
            }
        }
        
        _playbackState.value = currentState
    }
    
    /**
     * 播放单首歌曲
     *
     * @param song 要播放的歌曲
     */
    fun playSong(song: Song) {
        android.util.Log.d("MediaBrowserHelper", "播放单首歌曲: ${song.title}")
        
        if (mediaController == null) {
            android.util.Log.e("MediaBrowserHelper", "MediaController为空，无法播放")
            return
        }
        
        prepareSong(song, true)
    }
    
    /**
     * 准备单首歌曲
     * 
     * @param song 要准备的歌曲
     * @param playWhenReady 是否准备好后立即播放
     */
    fun prepareSong(song: Song, autoPlay: Boolean = true) {
        if (mediaController == null) return
        
        coroutineScope.launch {
            try {
                // 转换为MediaItem
                val mediaItem = MediaItem.Builder()
                    .setUri(song.url)
                    .setMediaId(song.id)
                    .setMediaMetadata(
                        MediaMetadata.Builder()
                            .setTitle(song.title)
                            .setArtist(song.artist)
                            .setAlbumTitle(song.album)
                            .setArtworkUri(Uri.parse(song.coverUrl))
                            .build()
                    )
                    .build()
                
                // 设置播放项
                mediaController?.setMediaItem(mediaItem)
                
                // 如果需要自动播放
                if (autoPlay) {
                    mediaController?.prepare()
                    mediaController?.play()
                }
                
                // 保存当前播放列表到数据库
                if (musicRepository is RoomMusicRepository) {
                    val currentPlaylist = CurrentPlaylistEntity(
                        sourceType = "SINGLE",
                        sourceId = "TEST",
                        currentSongId = song.id,
                        currentPosition = 0,
                        lastPlayedAt = System.currentTimeMillis()
                    )
                    (musicRepository as RoomMusicRepository).currentPlaylistDao.insertCurrentPlaylist(currentPlaylist)
                }
            } catch (e: Exception) {
                android.util.Log.e("MediaBrowserHelper", "准备单曲播放失败: ${e.message}")
            }
        }
    }
    
    /**
     * 播放歌曲列表
     *
     * @param songs 要播放的歌曲列表
     * @param startIndex 开始播放的歌曲索引
     */
    fun playPlaylist(songs: List<Song>, startIndex: Int = 0) {
        android.util.Log.d("MediaBrowserHelper", "播放列表，歌曲数量: ${songs.size}，起始索引: $startIndex")
        
        preparePlaylist(songs, startIndex, true)
    }
    
    /**
     * 准备播放列表
     */
    fun preparePlaylist(songs: List<Song>, startIndex: Int, autoPlay: Boolean = true) {
        if (mediaController == null) return
        
        coroutineScope.launch {
            try {
                // 转换为MediaItem列表
                val mediaItems = songs.map { song ->
                    MediaItem.Builder()
                        .setUri(song.url)
                        .setMediaId(song.id)
                        .setMediaMetadata(
                            MediaMetadata.Builder()
                                .setTitle(song.title)
                                .setArtist(song.artist)
                                .setAlbumTitle(song.album)
                                .setArtworkUri(Uri.parse(song.coverUrl))
                                .build()
                        )
                        .build()
                }
                
                // 设置播放列表
                mediaController?.setMediaItems(mediaItems)
                
                // 移动到指定位置
                mediaController?.seekTo(startIndex, 0)
                
                // 如果需要自动播放
                if (autoPlay) {
                    mediaController?.prepare()
                    mediaController?.play()
                }
                
                // 保存当前播放列表到数据库
                if (musicRepository is RoomMusicRepository) {
                    val currentPlaylist = CurrentPlaylistEntity(
                        sourceType = "PLAYLIST",
                        sourceId = "TEST",
                        currentSongId = songs[startIndex].id,
                        currentPosition = 0,
                        lastPlayedAt = System.currentTimeMillis()
                    )
                    (musicRepository as RoomMusicRepository).currentPlaylistDao.insertCurrentPlaylist(currentPlaylist)
                }
            } catch (e: Exception) {
                android.util.Log.e("MediaBrowserHelper", "准备播放列表失败: ${e.message}")
            }
        }
    }
    
    /**
     * 将歌曲转换为媒体项
     */
    private fun convertSongToMediaItem(song: Song): MediaItem {
        val mediaItem = MediaItem.Builder()
            .setMediaId(song.id)
            .setMediaMetadata(
                MediaMetadata.Builder()
                    .setTitle(song.title)
                    .setArtist(song.artist)
                    .setAlbumTitle(song.album)
                    .setArtworkUri(getArtworkUri(song))
                    .build()
            )
            .setUri(song.url)
            .build()
        
        return mediaItem
    }
    
    /**
     * 获取专辑封面URI
     */
    private fun getArtworkUri(song: Song): Uri? {
        return try {
            if (!song.coverUrl.isNullOrEmpty()) {
                Uri.parse(song.coverUrl)
            } else {
                null
            }
        } catch (e: Exception) {
            android.util.Log.e("MediaBrowserHelper", "解析专辑封面URI出错: ${e.message}")
            null
        }
    }
    
    /**
     * 切换播放/暂停
     */
    fun togglePlayPause() {
        val controller = mediaController ?: return
        
        if (controller.isPlaying) {
            controller.pause()
        } else {
            controller.play()
        }
    }
    
    /**
     * 跳到下一首
     */
    fun skipToNext() {
        mediaController?.seekToNextMediaItem()
    }
    
    /**
     * 跳到上一首
     */
    fun skipToPrevious() {
        mediaController?.seekToPreviousMediaItem()
    }
    
    /**
     * 跳到指定位置
     */
    fun seekTo(positionMs: Long) {
        mediaController?.seekTo(positionMs)
    }
    
    /**
     * 设置播放速度
     */
    fun setPlaybackSpeed(speed: Float) {
        mediaController?.setPlaybackSpeed(speed)
    }
    
    /**
     * 设置重复模式
     */
    fun setRepeatMode(repeatMode: Int) {
        mediaController?.repeatMode = repeatMode
    }
    
    /**
     * 设置随机播放模式
     */
    fun setShuffleMode(enabled: Boolean) {
        mediaController?.shuffleModeEnabled = enabled
    }
    
    /**
     * 通知收藏状态发生变化
     * 这个方法会通知MusicService更新收藏状态
     * @param songId 歌曲ID
     * @param isFavorite 新的收藏状态
     */
    fun notifyFavoriteStatusChanged(songId: String, isFavorite: Boolean) {
        // 检查当前播放的媒体项是否是这首歌
        val currentMediaItem = mediaController?.currentMediaItem
        if (currentMediaItem?.mediaId == songId) {
            // 创建包含新状态的Bundle
            val bundle = Bundle().apply {
                putString("songId", songId)
                putBoolean("isFavorite", isFavorite)
            }
            
            // 立即强制刷新通知栏
            coroutineScope.launch {
                try {
                    // 记录当前位置和播放状态（可能需要用于恢复）
                    val currentPosition = mediaController?.currentPosition ?: 0
                    val wasPlaying = mediaController?.isPlaying ?: false
                    
                    // 触发媒体控制器更新
                    forceUpdateNotification(songId, isFavorite)
                    
                    android.util.Log.d("MediaBrowserHelper", "通知收藏状态变化: $songId, 收藏=${isFavorite}")
                } catch (e: Exception) {
                    android.util.Log.e("MediaBrowserHelper", "通知收藏状态变化失败: ${e.message}")
                }
            }
        }
    }
    
    /**
     * 强制更新通知栏
     * 通过一个小技巧触发通知刷新
     */
    private fun forceUpdateNotification(songId: String, isFavorite: Boolean) {
        try {
            // 获取当前媒体项
            val currentMediaItem = mediaController?.currentMediaItem ?: return
            
            // 仅当是当前播放的歌曲时才触发更新
            if (currentMediaItem.mediaId == songId) {
                // 发送一个小的播放状态更改以触发通知刷新
                // 这是一个小技巧，先暂停然后立即恢复，会触发通知刷新
                val wasPlaying = mediaController?.isPlaying ?: false
                
                if (wasPlaying) {
                    // 触发一次轻微的播放状态变化，让媒体会话更新通知
                    mediaController?.playWhenReady = false
                    coroutineScope.launch {
                        delay(50) // 短暂延迟
                        mediaController?.playWhenReady = true
                    }
                } else {
                    // 如果当前已暂停，先播放再暂停
                    mediaController?.playWhenReady = true
                    coroutineScope.launch {
                        delay(50) // 短暂延迟
                        mediaController?.playWhenReady = false
                    }
                }
                
                android.util.Log.d("MediaBrowserHelper", "强制刷新通知: $songId, 收藏=${isFavorite}")
            }
        } catch (e: Exception) {
            android.util.Log.e("MediaBrowserHelper", "强制刷新通知失败: ${e.message}")
        }
    }
    
    /**
     * 播放器事件监听器
     */
    private val playerListener = object : Player.Listener {
        override fun onPlaybackStateChanged(playbackState: Int) {
            updatePlaybackState()
        }
        
        override fun onIsPlayingChanged(isPlaying: Boolean) {
            updatePlaybackState()
        }
        
        override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
            updatePlaybackState()
            
            // 当歌曲切换时，更新当前播放歌曲ID
            if (mediaItem != null && musicRepository is RoomMusicRepository) {
                coroutineScope.launch {
                    try {
                        (musicRepository as RoomMusicRepository).updateCurrentSong(mediaItem.mediaId)
                    } catch (e: Exception) {
                        android.util.Log.e("MediaBrowserHelper", "更新当前播放歌曲ID失败: ${e.message}")
                    }
                }
            }
        }
        
        override fun onPlayerError(error: androidx.media3.common.PlaybackException) {
            android.util.Log.e("MediaBrowserHelper", "播放错误: ${error.message}")
            
            _playbackState.value = PlaybackState.Error(error.message ?: "未知错误")
        }
    }
} 